#include "capfnode.h"

/**
 * CAPFNode - constructor, initialization
 * @param name
 * @param value
 * @param parentNodePtr
 */
CAPFNode::CAPFNode(string name, string value, CAPFNode* parentNodePtr) {
  this->init(name, value, parentNodePtr);
}
//---------------------------------------------------------------------------

/**
 * CAPFNode - copy constructor
 * @param node
 */
CAPFNode::CAPFNode(const CAPFNode &node) {
  copyFrom(node);
}
//---------------------------------------------------------------------------

/**
 * ~CAPFNode - destructor
 */
CAPFNode::~CAPFNode() {
  free();
}
//---------------------------------------------------------------------------

/**
 * operator= - copy assignment
 * @param node
 * @return this
 */
CAPFNode& CAPFNode::operator=(const CAPFNode &node) {
  free();
  copyFrom(node);
  return *this;
}
//---------------------------------------------------------------------------

/**
 * getName - returns name of node
 * @return node name
 */
string CAPFNode::getName() const {
  return name;
}
//---------------------------------------------------------------------------

/**
 * getValue - returns value of node
 * @return node value
 */
string CAPFNode::getValue() const {
  return value;
}
//---------------------------------------------------------------------------

/**
 * getSubNodesPtr - returns pointer on vector of sub-node pointers
 * @return pointer on vector of sub-node pointers
 */
vector<CAPFNode*>* CAPFNode::getSubNodesPtr() const {
  return subNodes;
}
//---------------------------------------------------------------------------

/**
 * getLatestSubNodePtr - returns pointer on latest sub-node
 * @return pointer on latest sub-node
 */
CAPFNode* CAPFNode::getLatestSubNodePtr() const {
  return subNodes->size() ? (*subNodes)[subNodes->size() - 1] : NULL;
}
//---------------------------------------------------------------------------

/**
 * getParentNodePtr - returns pointer on parent node
 * @return pointer on parent node
 */
CAPFNode* CAPFNode::getParentNodePtr() const {
  return parentNodePtr;
}
//---------------------------------------------------------------------------

/**
 * createSubNode - creates sub-node
 * @param name
 * @param value
 * @return pointer on new sub-node
 */
CAPFNode* CAPFNode::createSubNode(string name, string value) {
  subNodes->push_back(new CAPFNode(name, value, this));
  return getLatestSubNodePtr();
}
//---------------------------------------------------------------------------

/**
 * setValue - sets value of node
 * @param value
 */
void CAPFNode::setValue(string value) {
  this->value = value;
}
//---------------------------------------------------------------------------

/**
 * toString - prints info about node
 * @return string with node info
 */
string CAPFNode::toString() {
  string str = "name: " + name + "\n";
  str += "value: " + value + "\n";
  vector<CAPFNode*>::iterator i = subNodes->begin();
  if (subNodes != NULL) {
    for (; i < subNodes->end(); i++) {
      str += "subNode = {\n" + (*i)->toString() + "}\n";
    }
  }
  return str;
}
//---------------------------------------------------------------------------

/**
 * init - initialization
 * @param name
 * @param value
 * @param parentNodePtr
 */
void CAPFNode::init(string name, string value, CAPFNode* parentNodePtr) {
  subNodes = new vector<CAPFNode*> ();
  this->name = name;
  this->value = value;
  this->parentNodePtr = parentNodePtr;
}
//---------------------------------------------------------------------------

/**
 * copyFrom - copy from node
 * @param node
 */
void CAPFNode::copyFrom(const CAPFNode &node) {

  // Set variables
  init(node.name, node.value, NULL);

  // Copy sub-nodes
  vector<CAPFNode*>* s = node.getSubNodesPtr();
  for (vector<CAPFNode*>::const_iterator i = s->begin(); i < s->end(); i++) {
    subNodes->push_back(new CAPFNode());
    vector<CAPFNode*>::iterator latest = subNodes->end() - 1;
    (*latest)->copyFrom(**i);
    (*latest)->parentNodePtr = this;
  }
}
//---------------------------------------------------------------------------

/**
 * free - deletes all sub-nodes
 */
void CAPFNode::free() {
  if (subNodes && subNodes->size()) {
    vector<CAPFNode*>::iterator i = subNodes->begin();
    for (; i < subNodes->end(); i++) {
      (*i)->free();
      delete *i;
    }
    subNodes->clear();
    delete subNodes;
    subNodes = NULL;
  }
}
//---------------------------------------------------------------------------
